package main

import "fmt"

// Monkey 定义猴子的结构体
type Monkey struct {
	Name string
}

// ChildMonkey 定义children猴子的结构体
type ChildMonkey struct {
	Monkey
}

// 给Monkey绑定一个本身的方法
func (monkey *Monkey) climbing() {
	fmt.Println(monkey.Name, "生来会爬树...")
}

// BirdAble 声明一个BirdAble飞的接口
type BirdAble interface {
	Flying()
}

// FishAble 声明一个FishAble游泳的接口
type FishAble interface {
	Swimming()
}

// Flying 让ChildMonkey实现BirdAble
func (monkey *ChildMonkey) Flying() {
	fmt.Println(monkey.Name, "通过学习，会飞翔...")
}

// Swimming 让ChildMonkey实现FishAble
func (monkey *ChildMonkey) Swimming() {
	fmt.Println(monkey.Name, "通过学习，会有用...")
}

// Learning 让ChildMonkey实现一个学习方法，这个学习方法接受一个BirdAble接口类型变量和一个FishAble接口类型变
// 实现了鸟儿的飞翔和鱼儿的游泳
func (monkey *ChildMonkey) Learning(fly BirdAble, swim FishAble) {
	fly.Flying()
	swim.Swimming()
}

func main() {
	// 创建一个children猴子的实例
	childMonkey := ChildMonkey{
		Monkey{
			Name: "悟空",
		},
	}
	// 通过childMonkey调用继承Monkey的属性
	childMonkey.climbing()

	// childMonkey.Flying()
	// childMonkey.Swimming()
	// 这时，如果想在不破坏猴子的本身正常能力的方法，而增添其他功能的时候，可以使用接口方法
	// 猴子通过接口学习了飞翔和游泳
	childMonkey.Learning(&childMonkey, &childMonkey)
}
